#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
可视化服务模块
处理Petri网的可视化和导出
"""

import os
import tempfile
import subprocess
from PyQt5.QtWidgets import QGraphicsScene
from PyQt5.QtCore import Qt, QRectF
from PyQt5.QtGui import QPixmap
from pm4py.visualization.petri_net import visualizer as pn_visualizer

class VisualizationService:
    """可视化服务类，处理Petri网的可视化"""
    
    def __init__(self):
        """初始化可视化服务"""
        self.gviz = None
        self.temp_file = None
        self._check_graphviz()
    
    def _check_graphviz(self):
        """检查Graphviz是否可用"""
        try:
            # 尝试执行dot命令
            subprocess.run(['dot', '-V'], capture_output=True, check=True)
            print("Graphviz 检查通过")  # 调试信息
        except FileNotFoundError:
            print("未找到Graphviz，请确保已安装并添加到系统PATH")
            raise RuntimeError(
                "未找到Graphviz。请按以下步骤安装：\n"
                "1. 访问 https://graphviz.org/download/\n"
                "2. 下载并安装 Windows 版本\n"
                "3. 确保安装时选中'Add Graphviz to the system PATH'\n"
                "4. 重启程序"
            )
        except Exception as e:
            print(f"Graphviz检查失败: {str(e)}")
            raise RuntimeError(f"Graphviz检查失败: {str(e)}")
    
    def visualize_petri_net(self, net, initial_marking, final_marking):
        """可视化Petri网
        
        Args:
            net: Petri网对象
            initial_marking: 初始标记
            final_marking: 最终标记
            
        Returns:
            Gviz: 可视化对象
        """
        try:
            print("开始可视化Petri网")  # 调试信息
            
            # 设置可视化参数
            parameters = {
                "format": "png",
                "bgcolor": "transparent",
                "rankdir": "LR",  # 从左到右布局
                "fontsize": "10",
                "shape_place": "circle",
                "shape_transition": "box",
                "shape_final_marking": "doublecircle",
                "debug": True
            }
            
            # 创建可视化对象
            self.gviz = pn_visualizer.apply(
                net, 
                initial_marking, 
                final_marking,
                parameters=parameters
            )
            
            # 创建临时文件
            if self.temp_file:
                try:
                    os.remove(self.temp_file)
                except:
                    pass
            
            # 保存到临时文件
            self.temp_file = os.path.join(tempfile.gettempdir(), "petri_net_temp.png")
            pn_visualizer.save(self.gviz, self.temp_file)
            
            print("Petri网可视化完成")  # 调试信息
            return self.gviz
            
        except Exception as e:
            print(f"可视化错误: {str(e)}")  # 调试信息
            raise Exception(f"Petri网可视化失败: {str(e)}")
    
    def create_scene(self, gviz):
        """创建图形场景
        
        Args:
            gviz: 可视化对象
            
        Returns:
            QGraphicsScene: 图形场景
        """
        try:
            print("开始创建场景")  # 调试信息
            
            if not self.temp_file or not os.path.exists(self.temp_file):
                raise ValueError("找不到Petri网图像文件")
            
            # 创建场景
            scene = QGraphicsScene()
            
            # 加载图像
            pixmap = QPixmap(self.temp_file)
            if pixmap.isNull():
                raise ValueError("无法加载Petri网图像")
            
            # 添加到场景
            scene.addPixmap(pixmap)
            
            # 设置场景大小
            rect = pixmap.rect()
            scene.setSceneRect(QRectF(0, 0, rect.width(), rect.height()))
            
            print("场景创建完成")  # 调试信息
            return scene
            
        except Exception as e:
            print(f"场景创建错误: {str(e)}")  # 调试信息
            raise Exception(f"创建场景失败: {str(e)}")
    
    def export_petri_net(self, file_path, format='png'):
        """导出Petri网
        
        Args:
            file_path: 保存路径
            format: 导出格式 ('png' 或 'pdf')
        """
        try:
            print(f"开始导出Petri网到: {file_path}")  # 调试信息
            
            if self.gviz is None:
                raise ValueError("没有可导出的Petri网")
            
            # 确保目录存在
            os.makedirs(os.path.dirname(file_path), exist_ok=True)
            
            # 导出
            pn_visualizer.save(self.gviz, file_path)
            
            print("Petri网导出完成")  # 调试信息
            
        except Exception as e:
            print(f"导出错误: {str(e)}")  # 调试信息
            raise Exception(f"导出Petri网失败: {str(e)}")
    
    def cleanup(self):
        """清理资源"""
        try:
            print("开始清理可视化资源")  # 调试信息
            if self.gviz:
                self.gviz = None
            if self.temp_file:
                try:
                    os.remove(self.temp_file)
                except:
                    pass
                self.temp_file = None
            print("清理完成")  # 调试信息
        except Exception as e:
            print(f"清理错误: {str(e)}")  # 调试信息 